/*******************************************************************************
**
** Copyright (c) 2011 - The OWE Team
**
** This file is part of OWE.
**
** OWE is a free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; version
** version 2.1 of the License.
**
** OWE is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with OWE. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#include <tut/tut.hpp>
#include <tut/tut_console_reporter.hpp>

#include <owe/element.h>
#include <owe/nameelement.h>
#include <owe/textelement.h>
#include <owe/ustring.h>
#include <owe/widgetelement.h>

#include "utests.h"

OWE_USE_NAMESPACE

namespace tut
{
    test_runner_singleton runner;

    struct Element_data {};

    typedef test_group<Element_data> testgroup;
    testgroup shared_ptr_group("Element");
    typedef testgroup::object testobject;

    template<>
    template<>
    void testobject::test<1>() {
        set_test_name("Element *Element::fromNode(const Node *node)");

        Element *element;

        element = Element::fromNode(0);
        ensure(element->type() == Element::None);
        delete element;

        FakeNode invalid("asdfasdf");
        element = Element::fromNode(&invalid);
        ensure(element->type() == Element::None);
        delete element;

        FakeNode none(0); // Should never happen, but...
        element = Element::fromNode(&none);
        ensure(element->type() == Element::None);
        delete element;

        FakeNode widget("widget");
        element = Element::fromNode(&widget);
        ensure(element->type() == Element::Widget);
        ensure(dynamic_cast<WidgetElement *>(element));
        delete element;

        FakeNode name("name");
        element = Element::fromNode(&name);
        ensure(element->type() == Element::Name);
        ensure(dynamic_cast<NameElement *>(element));
        delete element;

        FakeNode text("text");
        element = Element::fromNode(&text);
        ensure(element->type() == Element::Text);
        ensure(dynamic_cast<TextElement *>(element));
        delete element;
    }

    template<>
    template<>
    void testobject::test<2>() {
        set_test_name("UString Element::lang() const");

        Element *element;

        FakeNode invalid("asdfasdf");
        invalid.addAttribute("xml:lang", "pt-br");
        element = Element::fromNode(&invalid);
        ensure(element->lang() == "");
        delete element;

        FakeNode test1("text");
        element = Element::fromNode(&test1);
        ensure(element->lang() == "");
        delete element;

        FakeNode test2("text");
        test2.addAttribute("xml:lang", "pt-br");
        element = Element::fromNode(&test2);
        ensure(element->lang() == "pt-br");
        delete element;
    }

    template<>
    template<>
    void testobject::test<3>() {
        set_test_name("UString Element::dir() const");

        Element *element;

        FakeNode invalid("asdfasdf");
        invalid.addAttribute("dir", "ltor");
        element = Element::fromNode(&invalid);
        ensure(element->dir() == "");
        delete element;

        FakeNode test1("text");
        element = Element::fromNode(&test1);
        ensure(element->dir() == "");
        delete element;

        FakeNode test2("text");
        test2.addAttribute("dir", "ltor");
        element = Element::fromNode(&test2);
        ensure(element->dir() == "ltor");
        delete element;
    }

    template<>
    template<>
    void testobject::test<4>() {
        set_test_name("bool TextElement::addText()");

        Element *element = Element::fromNode(0);

        FakeNode text1("text", "Some ");
        FakeNode text2("text", "content");
        ensure(element->addText(static_cast<TextElement *>(Element::fromNode(&text1))) == true);
        ensure(element->text() == "Some ");
        ensure(element->addText(static_cast<TextElement *>(Element::fromNode(&text2))) == true);
        ensure(element->text() == "Some content");
        ensure(element->addText(0) == true);
        delete element;
    }

    template<>
    template<>
    void testobject::test<5>() {
        set_test_name("bool Element::addChild(Element *element)");

        Element *element;

        FakeNode text("text");
        element = Element::fromNode(0);
        ensure(element->addChild(Element::fromNode(&text)) == false);
        delete element;
    }
}

int main(void)
{
    tut::console_reporter reporter;
    tut::runner.get().set_callback(&reporter);
    tut::runner.get().run_tests();

    return reporter.all_ok() ? 0 : 1;
}
